using System.ComponentModel;
using FluentSilverlight.Commands;
using FluentSilverlight.MVVM;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;

namespace FluentSilverlight.Tests
{
    [TestFixture]
    public class when_creating_viewmodel_with_creator
    {
        private MyModel model;
        private string lastPropChanged;

        [SetUp]
        public void SetUp()
        {
            model = new AutoNotifyPropertyChangedProxyCreator().Create<MyModel>();
            model.PropertyChanged += (s, e) => lastPropChanged = e.PropertyName;

            lastPropChanged = null;
        }

        [Test]
        public void should_send_property_changed_for_given_property()
        {
            model.Name = "test";

            Assert.That(lastPropChanged, Is.EqualTo("Name"));
            Assert.That(model.Name, Is.EqualTo("test"));
        }

        [Test]
        public void should_allow_to_mark_specific_properties_to_not_notify_changes()
        {
            model.Status = "test status";

            Assert.That(lastPropChanged, Is.Null);
            Assert.That(model.Status, Is.EqualTo("test status"));
        }

        [Test]
        public void should_not_notify_property_changed_for_a_command_type_property()
        {
            var command = new DelegateCommand<object>(a => { });
            model.TestCommand = command;

            Assert.That(lastPropChanged, Is.Null);
            Assert.That(model.TestCommand, Is.SameAs(command));
        }
    }

    public abstract class MyModel : IAutoNotifyPropertyChanged
    {
        public virtual string Name { get; set; }
        public virtual int Age { get; set; }

        [DoNotNotifyChanges]
        public virtual string Status { get; set; }

        public virtual DelegateCommand<object> TestCommand { get; set; }
        
        public event PropertyChangedEventHandler PropertyChanged;
        
        public void OnPropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}